package com.qfedu.entity.course01;

public class MyLinkedList<E> {
    //头节点
    private Node<E> head = new Node();

    public E getByIndex(int index) {
        //当前节点
        Node<E> node = head.next;
        //当前位置
        int pos = 0;
        //遍历位置到目标索引
        while (node != null && pos != index) {
            //将下一个节点作为当前节点
            node = node.next;
            //当前位置+1
            pos++;
        }
        if (pos == index) {
            //返回查找位置的值
            return node.item;
        }
        return null;
    }

    public void insertAtIndex(int index, E val) {
        if (index == 0) {
            //在头部插入
            Node<E> newNode = new Node(val);
            //原链表第一个节点
            final Node<E> oldFirst = head.next;
            //头节点指向新创建的节点
            head.next = newNode;
            //新创建节点指向 原链表的第一个节点
            newNode.next = oldFirst;
        } else {
            //查找插入位置的前一个节点
            Node preNode = head.next;
            //当前位置
            int pos = 0;
            //遍历位置到目标位置的前一个节点
            while (preNode != null && pos != (index - 1)) {
                //将下一个节点作为当前节点
                preNode = preNode.next;
                //当前位置+1
                pos++;
            }
//            preNode=getNodeByIndex(index-1);
            if (pos == (index - 1)) {
                //目标位置的原始节点
                Node oldNode = preNode.next;
                //将目标位置的原始节点作为新节点的后继结点(next)
                Node node = new Node(val);
                node.next = oldNode;
                //目标位置的前一个节点指向新节点
                preNode.next = node;
            }
        }
    }

    public Node<E> getNodeByIndex(int index) {
        //当前节点
        Node<E> node = head.next;
        //当前位置
        int pos = 0;
        //遍历位置到目标索引
        while (node != null && pos != index) {
            //将下一个节点作为当前节点
            node = node.next;
            //当前位置+1
            pos++;
        }
        //返回节点
        return node;
    }

    public void removeAtIndex(int index) {
        if (index == 0) {
            //通过头指针获取第一个节点
            Node first = head.next;
            if (first != null) {
                //获取第二个节点
                Node second = first.next;
                //头指针执行第二个节点（从而实现了对第一个节点的删除）
                head.next = second;
            }
        } else {
            //获取目标位置的前一个节点
            Node<E> preNode = getNodeByIndex(index - 1);
            if (preNode != null && preNode.next != null) {
                //通过前一个节点的next找到目标节点，再通过目标节点的next找到后一个节点
                preNode.next = preNode.next.next;
            }
        }
    }

    public void print() {
        StringBuilder sb = new StringBuilder("head");
        Node<E> node = head.next;
        while (node != null) {
            sb.append("-->" + node.item);
            node = node.next;
        }
        System.out.println(sb.toString());
    }

    public static void main(String[] args) {
        MyLinkedList<Integer> myLinkedList = new MyLinkedList<>();
        for (int i = 0; i < 10; i++) {
            myLinkedList.insertAtIndex(i, i);
        }
        myLinkedList.print();
        myLinkedList.removeAtIndex(0);
        myLinkedList.print();
        myLinkedList.insertAtIndex(0, 0);
        myLinkedList.print();
        myLinkedList.insertAtIndex(10, 10);
        myLinkedList.print();
        myLinkedList.insertAtIndex(7, -7);
        myLinkedList.print();
        myLinkedList.removeAtIndex(7);
        myLinkedList.print();
    }
}
